package com.cloudfun.campusshare.listener;

import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.constant.RedisKey;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.dto.dingtalk.TextContent;
import com.cloudfun.campusshare.device.protocol.command.CheckDeviceStatus;
import com.cloudfun.campusshare.repo.DeviceEntityRepo;
import com.cloudfun.campusshare.service.DeviceService;
import com.cloudfun.campusshare.service.DingTalkService;
import com.cloudfun.msgsubscribe.DeviceInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.orm.ObjectOptimisticLockingFailureException;

import java.util.concurrent.CompletableFuture;

/**
 * Created by Huqin on 2020/9/9
 */
@Slf4j
public abstract class AbstractDeviceMsgListener {

    @Autowired
    protected DeviceService deviceService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DingTalkService dingTalkService;

    @Autowired
    private DeviceEntityRepo deviceEntityRepo;

    @RabbitHandler
    public void process(DeviceInfo deviceInfo) {
        log.debug("收到2G设备消息: {}", deviceInfo);
        String imei = deviceInfo.getImei();
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(RedisKey.IMEI_SET, imei);
        if (!isMember) {
            log.debug("imei为：{}的2G消息不在本系统中，忽略消息：{}", imei, deviceInfo);
            return;
        }
        // 校验设备状态
//        CompletableFuture.runAsync(new CheckDeviceStatus(deviceEntityRepo,imei));
        try {
            boolean processSuccess = false;
            for (int i = 0; i < 5; i++) {
                try {
                    deviceService.updateInteractionTime(deviceInfo.getImei(), deviceInfo.getTimestamp());
                    this.doProcess(deviceInfo);
                    processSuccess = true;
                    break;
                } catch (ObjectOptimisticLockingFailureException oplfe) {
                    log.error("2G设备消息：{}, 处理时乐观锁异常", deviceInfo, oplfe);
                }
            }
            if (!processSuccess) {
                throw new BusinessException(Code.ERROR, "乐观锁失败，且超过最大重试次数：" + 5);
            }
        } catch (Exception e) {
            log.error("2G设备消息：{}, 处理异常", deviceInfo, e);
            TextContent textContent = new TextContent("imei为：" + deviceInfo.getImei() + "的2G设备消息处理异常：" + e);
            dingTalkService.sendMessage(textContent);
        }
    }

    protected abstract void doProcess(DeviceInfo deviceInfo);

}
